#############################################################
#所有的执行都需要在python解析器中执行,推荐安装ipython       #
#pip install ipython                                        #
#每一个功能模块都可以单独执行                               #
#############################################################

from functools import reduce
import os,re,pathlib,xmltodict,hashlib
import xml.etree.ElementTree as et
from  hundsun_config import *
while True:
    input_str='请输入需要的环境,['+','.join([' '+str(x[0])+'  '+x[1][0]+' ' for x in enumerate(DICT_ENV)])+'其它值 生产 q 退出]:'
    env_flag=input(input_str)
    if env_flag == 'q':
        os._exit(0)
    elif env_flag in [str(x[0]) for x in enumerate(DICT_ENV)]:
        all_user_str=reduce(lambda x,y :  x.replace(y,DICT_ENV[int(env_flag)][1]) ,[ALL_USER_STR]+list(set([z.split(':')[1] for z in ALL_USER_STR.split(';') if z ])))
        filter_user=[x+':'+ DICT_ENV[int(env_flag)][1] for x in DICT_ENV[int(env_flag)][2:] if x ]
        allow_user_str=';'.join([w for w in reduce(lambda x,y :  x.replace(y,'') ,[all_user_str]+filter_user).split(';') if w ])
        dict_use={DICT_ENV[int(env_flag)][1]:'hundsun' for x,y in DICT_USE.items()}
        break
    elif env_flag == '':
        print('输入不能为空')
    else:
        all_user_str=ALL_USER_STR
        allow_user_str=ALL_USER_STR
        dict_use=DICT_USE
        break
        
while True:
    input_str='按照提示输入信息:\r\n 1:检查合并后的sql文件中是否有错误的数据库连接 \r\n 2:查看config_as.xml或config_ls.xml中so加载项是否有重复内容\r\n 3:检查mdb.xml文件中内存表中是否有重复的配置 \r\n 4:检查config_as.xml或config_ls.xml文件加载的so是否存在真实的文件 \r\n 5:q 退出\r\n 请输入:'
    exec_flag=input(input_str)
    if exec_flag == 'q':
        os._exit(0)
    elif exec_flag =='1':
        ######################################################################
        #1、检测是否有连接数据库错误的 
        ######################################################################
        #文件为合并以后的脚本,可以通过如下程序检查是否有conn中用户与所在库连接不一致的情况
        dict_user_dict={ x.split(':')[0]:x.split(':')[1] for x in all_user_str.split(';')}
        line_no=0    
        while True:
            input_str='请输入检查的文件全路径,q 退出]:'
            file_name=input(input_str)
            if file_name == 'q':
                os._exit(0)
            elif file_name =='' or ( not pathlib.Path(file_name).exists()):
                print('输入不能为空或者输入文件不存在')
            else:
                error_lines=list()
                with open(file_name,'r') as f:
                    line=f.readline()
                    while line:
                        if re.search('^conn.*',line):
                            if dict_user_dict[line.split(' ')[1].split('/')[0]] !=line.split(' ')[1].split('@')[1].strip():
                                error_lines.append(line)
                                line_no=line_no+1
                        line=f.readline()
                
                break
        if line_no == 0:
            print('#'*108)
            print('{:#^108}'.format('no error connect'))
            print('#'*108)
        else:
            print('#'*108)
            print('{:#^108}'.format(('total errors connect :'+str(line_no))))
            print('#'*108)
            [print(str(x)) for x in error_lines]
    

    elif exec_flag =='2':
    ######################################################################
    #2、以下信息为如何规避xml配置文件中重复的组件 ，适用于so文件，不适用于内存表
    #D:\hundsun_sj\01UF20\xml\config_as.xml 为ls或者是as的配置文件
    ######################################################################

        while True:
            input_str='请输入config_as.xml或config_ls.xml文件全路径,q 退出]:'
            file_name=input(input_str)
            if file_name == 'q':
                os._exit(0)
            elif file_name =='' or ( not pathlib.Path(file_name).exists()):
                print('输入不能为空或者输入文件不存在')
            else:
                #with open(file_name) as f:
                #    content=f.read()
                c=et.fromstring(pathlib.Path(file_name).read_text())
                all_dict=dict()
                double_dict=dict()
                count_dict=dict()

                for x in c.iterfind('.//component'):
                    #print(xmltodict.parse(et.tostring(x)))
                    md5=hashlib.md5()
                    w=xmltodict.parse(et.tostring(x))
                    md5.update(str(w).encode('utf-8'))
                    res=md5.hexdigest()
                    table_name=w.get('component').get('@dll')
                    if table_name in all_dict.keys():
                        double_dict[table_name]=res
                        if table_name in count_dict.keys():
                            count_dict[table_name]==count_dict[table_name]+1
                        else:
                            count_dict[table_name]=2
                    else:
                        all_dict[table_name]=res

                if double_dict:
                    print('#'*108)
                    print('{:#^108}'.format('having multi config'))
                    print('#'*108)
                    print('dll_name'.ljust(32),'count'.ljust(6),'hash-1'.ljust(35),'hash-2'.ljust(35))
                    for k,v in double_dict.items():
                        print(k.ljust(32),str(count_dict[k]).ljust(6),all_dict[k].ljust(35),double_dict[k].ljust(35))
                else:
                    print('#'*108)
                    print('没有重复的配置项目')
                    print('#'*108)
            break
    elif exec_flag =='3':
        ######################################################################   
        #3、以下信息为检查内存表中是否有重复的内存表信息：
        #D:\hundsun_sj\01UF20\xml\hsmdb.xml 为内存表的配置文件
        ######################################################################


        while True:
            input_str='请输入mdb.xml文件全路径,q 退出]:'
            file_name=input(input_str)
            if file_name == 'q':
                os._exit(0)
            elif file_name =='' or ( not pathlib.Path(file_name).exists()):
                print('输入不能为空或者输入文件不存在')
            else:
                with open(file_name) as f:
                    content=f.read()
                c=et.fromstring(content)
                all_dict=dict()
                double_dict=dict()
                count_dict=dict()

                for x in c.iterfind('.//table'):
                    md5=hashlib.md5()
                    w=xmltodict.parse(et.tostring(x))
                    md5.update(str(w).encode('utf-8'))
                    res=md5.hexdigest()
                    table_name=w.get('table').get('@name')
                    if table_name in all_dict.keys():
                        double_dict[table_name]=res
                        if table_name in count_dict.keys():
                            count_dict[table_name]==count_dict[table_name]+1
                        else:
                            count_dict[table_name]=2
                    else:
                        all_dict[table_name]=res

                if double_dict:
                    print('#'*108)
                    print('{:#^108}'.format('having multi tables:'))
                    print('#'*108)
                    print('table_name'.ljust(32),'count'.ljust(6),'hash-1'.ljust(35),'hash-2'.ljust(35))
                    for k,v in double_dict.items():
                        print(k.ljust(32),str(count_dict[k]).ljust(6),all_dict[k].ljust(35),double_dict[k].ljust(35))
                else:
                    print('#'*108)
                    print('没有重复的配置项目')
                    print('#'*108)
            break
    elif exec_flag =='4':
  
            
        ######################################################################
        #5、检查xml文件加载的so是否存在真实的文件
        ######################################################################
        # D:\test\appcom\appcom中为所有存服务器上下载的so文件
        # D:\test\20180727\config_ls.xml 为生产中使用的xml文件



        while True:
            input_str='请输入config_as.xml或config_ls.xml文件全路径,q 退出]:'
            file_name=input(input_str)
            if file_name == 'q':
                os._exit(0)
            elif file_name =='' or ( not pathlib.Path(file_name).exists()):
                print('输入不能为空或者输入文件不存在')
            else:
                input_str='请输入appcom文件夹全路径,q 退出]:'
                appcom_dir=input(input_str)
                if appcom_dir == 'q':
                    os._exit(0)
                elif appcom_dir =='' or ( not pathlib.Path(appcom_dir).exists()):
                    print('输入不能为空或者输入文件不存在')
                else:
                    appcoms=[x.name[3:-3] for x in pathlib.Path(appcom_dir).glob('*.so')]
                    with open(file_name,'r') as f:
                        txt=f.read()
                    tree=et.fromstring(txt)
                    xml_appcom=[x.attrib['dll'] for x in tree.iter('component')]
                    list_result=[x for x in xml_appcom if x not in appcoms]
                
                    print('#'*108)
                    if list_result:
                        print('{:#^108}'.format('so file name in filename:'+pathlib.Path(file_name).name+',but not in appcom dir'))
                        print('#'*108)
                        [print(x) for x in list_result]
                    else:
                        print('{:#^108}'.format('all file name filename:'+str(file_name)+' also in appcom dir'))
                        print('#'*108)
                    
                break
